import logging
import os
from fastapi import FastAPI, Depends, HTTPException
from fastapi.responses import JSONResponse
from data_models.models import AddCategoryRequest, DeleteCategoryRequest

from utils.async_utils import run_in_thread_pool

# 导入统一的日志配置模块
from log_config import setup_logging, shutdown_logging
# 配置日志
setup_logging()
logger = logging.getLogger(__name__)

# 创建分类图片目录的辅助函数
def create_category_image_dir(embedding_service, category_name):
    """
    在配置的saved_images_dir目录下创建对应的分类子目录
    
    :param embedding_service: 嵌入服务实例
    :param category_name: 分类名称
    """
    try:
        # 获取saved_images_dir配置，直接从embedding_service的image_dir属性获取
        saved_images_dir = embedding_service.image_dir
        # 创建分类对应的子目录路径
        category_dir = os.path.join(saved_images_dir, category_name)
        
        # 检查目录是否存在，不存在则创建
        if not os.path.exists(category_dir):
            os.makedirs(category_dir, exist_ok=True)
            logger.info(f"成功创建分类图片目录: {category_dir}")
    except Exception as e:
        logger.error(f"创建分类图片目录失败: {str(e)}")
        # 这里不抛出异常，因为目录创建失败不应该影响分类添加的主要功能

# 删除分类图片目录的辅助函数
def delete_category_image_dir(embedding_service, category_name):
    """
    删除配置的saved_images_dir目录下对应的分类子目录
    
    :param embedding_service: 嵌入服务实例
    :param category_name: 分类名称
    """
    try:
        # 获取saved_images_dir配置，直接从embedding_service的image_dir属性获取
        saved_images_dir = embedding_service.image_dir
        # 创建分类对应的子目录路径
        category_dir = os.path.join(saved_images_dir, category_name)
        
        # 检查目录是否存在，如果存在则删除
        if os.path.exists(category_dir):
            # 使用os.rmdir删除空目录，如果需要删除非空目录可以考虑shutil.rmtree
            # 但这里使用rmdir更安全，避免意外删除包含文件的目录
            os.rmdir(category_dir)
            logger.info(f"成功删除分类图片目录: {category_dir}")
    except Exception as e:
        logger.error(f"删除分类图片目录失败: {str(e)}")
        # 这里不抛出异常，因为目录删除失败不应该影响分类删除的主要功能

# 注册分类相关路由
def register_category_routes(app: FastAPI, get_embedding_service, get_thread_pool):
    """
    注册分类管理相关的API路由
    包括添加分类、获取分类列表和删除分类等功能
    
    :param app: FastAPI应用实例
    :param get_embedding_service: 获取嵌入服务的依赖注入函数
    :param get_thread_pool: 获取线程池的依赖注入函数
    """
    @app.post("/add_category")
    async def add_category(request: AddCategoryRequest, 
                         embedding_service=Depends(get_embedding_service),
                         thread_pool=Depends(get_thread_pool)):
        """
        浏览器提交添加分类
        
        :param request: 请求对象，包含分类名称和描述
        :param embedding_service: 通过依赖注入获取的嵌入服务实例
        :param thread_pool: 通过依赖注入获取的线程池实例
        :return: 包含操作状态和消息的JSON响应
        :raises HTTPException: 当操作失败时抛出500错误
        """
        try:
            name = request.name.strip()
            desc = request.desc.strip()
            logger.info(f"开始添加分类, 收到参数: name:{name}, desc:{desc}")
            
            # 使用线程池执行同步的分类添加操作，避免阻塞事件循环
            await run_in_thread_pool(
                thread_pool,
                lambda: (
                    embedding_service.category_manager.add_category_with_desc(name, desc),
                    # 刷新分类列表
                    embedding_service._init_collection(),
                    # 创建对应的图片保存子目录
                    create_category_image_dir(embedding_service, name)
                )
            )
        
            return JSONResponse(content={
                "success": True,
                "message": "分类添加成功",
            }, status_code=200)
        except ValueError as e:
            logger.error(f"添加分类失败(参数验证): {str(e)}")
            raise HTTPException(status_code=400, detail=f"添加分类失败: {str(e)}")
        except Exception as e:
            logger.error(f"添加分类失败(系统错误): {str(e)}")
            raise HTTPException(status_code=500, detail=f"添加分类失败: {str(e)}")

    @app.get("/get_category")
    async def get_category_list(embedding_service=Depends(get_embedding_service),
                               thread_pool=Depends(get_thread_pool)):
        """
        获取所有分类列表
        
        :param embedding_service: 通过依赖注入获取的嵌入服务实例
        :param thread_pool: 通过依赖注入获取的线程池实例
        :return: 包含操作状态、消息和分类列表的JSON响应
        :raises HTTPException: 当操作失败时抛出500错误
        """
        try:
            # 从分类管理器获取分类列表，使用线程池避免阻塞事件循环
            category_list = await run_in_thread_pool(
                thread_pool,
                embedding_service.category_manager.get_all_categories
            )
            return JSONResponse(content={
                "success": True,
                "message": "分类获取成功",
                "category_list": category_list
            }, status_code=200)
        except Exception as e:
            logger.error(f"获取分类失败: {e}")
            raise HTTPException(status_code=500, detail="获取分类失败")

    @app.delete("/delete_category")
    async def delete_category(request: DeleteCategoryRequest, 
                            embedding_service=Depends(get_embedding_service),
                            thread_pool=Depends(get_thread_pool)):
        """
        删除指定的分类
        
        :param request: 请求对象，包含要删除的分类名称
        :param embedding_service: 通过依赖注入获取的嵌入服务实例
        :param thread_pool: 通过依赖注入获取的线程池实例
        :return: 包含操作状态和消息的JSON响应
        :raises HTTPException: 当操作失败时抛出500错误
        """
        try:
            category_name = request.category_name

            # 删除分类，使用线程池执行同步操作避免阻塞事件循环
            await run_in_thread_pool(
                thread_pool,
                lambda: (
                    embedding_service.category_manager.remove_category(category_name),
                    embedding_service.remove_collection(category_name),
                    # 删除对应的图片保存子目录
                    delete_category_image_dir(embedding_service, category_name)
                )
            )
        
            return JSONResponse(content={
                "success": True,
                "message": "分类删除成功"
            }, status_code=200)
        except Exception as e:
            logger.error(f"删除分类失败: {str(e)}")
            raise HTTPException(status_code=500, detail=f"删除分类失败: {str(e)}")